using System;
using System.Collections.Generic;
using QuickBencher;
using System.Diagnostics;
using System.Globalization;

namespace SampleBenchmarks
{
    public class List_enumeration : Runnable
    {
        public void Run()
        {
            var list = new List<string>();
            for (int i = 0; i < 10000000; i++)
                list.Add(i.ToString());

            string dummy;

            Console.WriteLine("Use Measure() to measure the time:");
            Benchmark.Measure(() => { foreach (var item in list) dummy = item; });
            Console.WriteLine();

            Console.WriteLine("Do some experiments sequentially using the Bm() method:");
            Benchmark.Bm(x =>
            {
                x.Report(() => { list.ForEach(s => dummy = s); });
                x.Report(() => { for (int i = 0; i < list.Count; i++) dummy = list[i]; });
                x.Report(() => { foreach (var item in list) dummy = item; });
            });
            Console.WriteLine();

            Console.WriteLine("Continuing the previous example, put a label in each report:");
            Benchmark.Bm(x =>
            {
                x.Report("For:", ()
                    => { for (int i = 0; i < list.Count; i++) dummy = list[i]; });
                x.Report("While:", ()
                    => { var enu = list.GetEnumerator(); while (enu.MoveNext()) dummy = enu.Current; });
                x.Report("Foreach:", ()
                    => { foreach (var item in list) dummy = item; });
                x.Report("Lambda:", ()
                    => { list.ForEach(s => dummy = s); });
            });
            Console.WriteLine();

            Console.WriteLine("And finally use the Bmbm method:");
            Benchmark.Bmbm(x =>
            {
                x.Report("For:", () => { for (int i = 0; i < list.Count; i++) dummy = list[i]; });
                x.Report("While:", () => { var enu = list.GetEnumerator(); while (enu.MoveNext()) dummy = enu.Current; });
                x.Report("Foreach:", () => { foreach (var item in list) dummy = item; });
                x.Report("Lambda:", () => { list.ForEach(s => dummy = s); });
            });
            Console.WriteLine();

            RunWithNormalMeasurementStyle();
        }
        private void RunWithNormalMeasurementStyle()
        {
            var list = new List<string>();
            for (int i = 0; i < 10000000; i++)
                list.Add(i.ToString());

            string dummy;

            Console.WriteLine("For comparison - run the same tests without QuickBencher...");
            var watch = Stopwatch.StartNew();
            for (int i = 0; i < list.Count; i++) dummy = list[i];
            watch.Stop();
            Report("For", watch);

            watch = Stopwatch.StartNew();
            var enu = list.GetEnumerator(); while (enu.MoveNext()) dummy = enu.Current;
            watch.Stop();
            Report("While", watch);

            watch = Stopwatch.StartNew();
            foreach (var item in list) dummy = item;
            watch.Stop();
            Report("Foreach", watch);

            watch = Stopwatch.StartNew();
            list.ForEach(s => dummy = s);
            watch.Stop();
            Report("Lambda", watch);
        }

        private static void Report(string label, Stopwatch watch)
        {
            var realTime = watch.ElapsedMilliseconds / 1000d;
            Console.WriteLine("{0}: {1}", label, realTime.ToString("F6", CultureInfo.CreateSpecificCulture("en-US")));
        }
    }
}

